﻿/************************************************************************************
 * @author   wangjian
 * 	控制手与车交互的脚本
 * 	
 *  抓取使用低模（小车），放大使用的诗高模
 * 
 * 
************************************************************************************/


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using DG.Tweening;

public enum CarShowState{
	NONE,
	NORMAL,	        //正常（小，显示低模）
	GRABING,		//抓ing
	GRABED,			//抓住
	THROWING,		//抛中
	FALLED,			//落地
	ZOOM_ININFG,	//放大中
	BIG,			//变大（大，显示高模）
	ZOOM_OUTING,    //缩小中

	ROLLBACK,		//回滚，重置

}


public class CarObjectInteraction :MonoBehaviour {




	public GameObject lowCarModel;
	public GameObject hightCarModel;

	public HandSuckBall handSuckBall;

	Rigidbody lowCarRig;
	Rigidbody hightCarlRig;

	public Vector3 originPosition; 

	public CarShowState _currentState = CarShowState.NONE;

	public CarShowState CurrentState{
		set{ 
			_currentState = value;
			Debug.LogError ("Current State:"+_currentState);
		}
		get{
			return _currentState;
		}
	}



	public bool isStartThrow = false;

	public CollisionListener lowCarRigCollisionListener;
	public CollisionListener hightCarRigCollisionListener;
	void Start(){
		
		lowCarRig = lowCarModel.GetComponent<Rigidbody> ();
		hightCarlRig =  hightCarModel.GetComponent<Rigidbody>();
		CurrentState = CarShowState.NORMAL;
		lowCarRigCollisionListener = lowCarModel.GetComponent<CollisionListener> ();
		hightCarRigCollisionListener = hightCarModel.GetComponent<CollisionListener>();

		lowCarRigCollisionListener.OnCollisionEnterCallBack += OnLowModelCollisionEnter;
		lowCarRigCollisionListener.OnCollisionStayCallBack += OnLowModelCollisionStay;
		lowCarRigCollisionListener.OnCollisionExitCallBack += OnLowModelCollisionExit;

		hightCarRigCollisionListener.OnCollisionEnterCallBack += OnHightModelCollisionEnter;
		hightCarRigCollisionListener.OnCollisionStayCallBack += OnHightModelCollisionStay;
		hightCarRigCollisionListener.OnCollisionExitCallBack += OnHightModelCollisionExit;

	}

	void OnDestory(){

		lowCarRigCollisionListener.OnCollisionEnterCallBack -= OnLowModelCollisionEnter;
		lowCarRigCollisionListener.OnCollisionStayCallBack -= OnLowModelCollisionStay;
		lowCarRigCollisionListener.OnCollisionExitCallBack -= OnLowModelCollisionExit;

		hightCarRigCollisionListener.OnCollisionEnterCallBack -= OnHightModelCollisionEnter;
		hightCarRigCollisionListener.OnCollisionStayCallBack -= OnHightModelCollisionStay;
		hightCarRigCollisionListener.OnCollisionExitCallBack -= OnHightModelCollisionExit;
	}



	public int pointCount = 0;

	public int frameLimit = 0;

	public List<Vector3> points = new List<Vector3>();
	public List<Vector3> eulerList = new List<Vector3>();

	public int index = 0;

	public void Update(){
		
		if (CurrentState == CarShowState.THROWING) {
			frameLimit++;
			if (frameLimit > 2|| pointCount == 0) {
				if(frameLimit > 2) frameLimit = 0;
				AddPoint ();

			}
			
		}

		if (CurrentState == CarShowState.ROLLBACK && points.Count>0) {

			if (index < points.Count - 1) {
				Vector3 p = points [index];
				Vector3 e = eulerList [index];

				lowCarModel.transform.position = p;
				lowCarModel.transform.eulerAngles = e;
			}

			if (index >= points.Count - 1) {
				Vector3 p = points [points.Count - 1];
				Vector3 e = eulerList [points.Count - 1];

				lowCarModel.transform.position = p;
				lowCarModel.transform.eulerAngles = e;


			}
			
		}



	}
	void AddPoint(){
		Debug.LogError ("pointCount:"+pointCount);
		Vector3 p = lowCarModel.transform.position;
		GameObject sphere= GameObject.CreatePrimitive (PrimitiveType.Sphere);
		Destroy (sphere.GetComponent<SphereCollider> ());
		sphere.transform.localScale = new Vector3 (0.1f,0.1f,0.1f);
		sphere.transform.position = p;
		sphere.transform.GetComponent<MeshRenderer> ().material.color = Color.red;
		points.Add (p);
		eulerList.Add (lowCarModel.transform.eulerAngles);
	}

	string targetAreaCollisionName = "TargetArea";


	public void OnLowModelCollisionEnter(Collision other){
		Debug.LogError ("OnLowModelCollisionEnter :"+other.collider.name);

		if (other.collider.name.Equals (targetAreaCollisionName)) {
			CarFallComplete ();
		}


	}

	public void OnLowModelCollisionStay(Collision other){
		//Debug.LogError ("OnLowModelCollisionStay :"+other.collider.name);

	}

	public void OnLowModelCollisionExit(Collision other){
		//Debug.LogError ("OnLowModelCollisionExit :"+other.collider.name);

	}



	public void OnHightModelCollisionEnter(Collision other){
		//Debug.LogError ("OnHightModelCollisionEnter :"+other.collider.name);
	}

	public void OnHightModelCollisionStay(Collision other){

		//Debug.LogError ("OnHightModelCollisionStay :"+other.collider.name);
	}

	public void OnHightModelCollisionExit(Collision other){
		
		//Debug.LogError ("OnHightModelCollisionExit :"+other.collider.name);
	}


	#region carObject method


	//生成初始化
	public void Generate(){
	
		
	}
	public delegate void OnGrabComplete();

	//手柄抓取小车模型
	public void GrabCar(HandSuckBall _handSuckBall,OnGrabComplete method){
		if (CurrentState == CarShowState.GRABING || CurrentState == CarShowState.GRABED)
			return;
		Debug.LogError ("GrabCar "+gameObject.name);

		handSuckBall = _handSuckBall;
		Rigidbody SuckBallRig = _handSuckBall.HandRig;
		CurrentState = CarShowState.GRABING;

		if (SuckBallRig.gameObject.GetComponent<FixedJoint> () ==null) {

			lowCarRig.GetComponent<BoxCollider> ().enabled = false;

			Vector3 endPosition = handSuckBall.suckEffObj.transform.position;

			//lowCarRig.isKinematic = true;

			Tweener tween = lowCarRig.transform.DOMove (endPosition,0.8f);
			tween.SetEase (Ease.OutExpo);

			tween.OnComplete( delegate() {
				FixedJoint joint = SuckBallRig.gameObject.AddComponent<FixedJoint> ();
				joint.connectedBody = lowCarRig;

				CurrentState = CarShowState.GRABED;
				if(method!=null)
					method();

				TweenComplete(CompleteType.Grap);
			});
		}
	}

	//抓住了，释放车模
	void ReleaseCar(){
		Debug.LogError ("ReleaseCar "+gameObject.name);
		if (handSuckBall != null && CurrentState == CarShowState.GRABED) {
			FixedJoint joint = handSuckBall.GetComponent<FixedJoint> ();
			if (joint != null) {
				joint.connectedBody = null;
				Destroy (joint);
				handSuckBall = null;

				lowCarRig.GetComponent<BoxCollider> ().enabled = true;
				CurrentState = CarShowState.NORMAL;
			}
		}
	}

	//抛车模
	public void ThrowCar(Vector3 velocity, Vector3 angularVelocity){
		Debug.LogError ("ThrowCar "+gameObject.name);
		if (handSuckBall != null) {
			FixedJoint joint = handSuckBall.GetComponent<FixedJoint> ();
			if (joint != null) {
				joint.connectedBody = null;
				Destroy (joint);
				handSuckBall = null;
				//lowCarRig.AddForce (velocity * 10);
				//lowCarRig.angularVelocity = angularVelocity;
				lowCarRig.AddForce (new Vector3 (0, 500, 500));
				lowCarRig.GetComponent<BoxCollider> ().enabled = true;
				AddPoint ();
				CurrentState = CarShowState.THROWING;
			}
		}

	}

	//落地
	void CarFallComplete(){
		if (CurrentState != CarShowState.THROWING && CurrentState != CarShowState.FALLED)
			return;
		CurrentState = CarShowState.FALLED;

		lowCarModel.SetActive (false);


		hightCarModel.transform.position = lowCarModel.transform.position;
		hightCarModel.transform.localScale = lowCarModel.transform.localScale;

		hightCarModel.SetActive (true);
		Vector3 endLocalEuler = new Vector3 (0,-90,0);

		Tweener tween = hightCarModel.transform.DOLocalRotate (endLocalEuler,0.2f);
		tween.SetEase (Ease.Linear);

		tween.OnComplete( delegate() {
			TweenComplete(CompleteType.Fall);
		});

	}

	//放大放小高模

	public void ZoomCar(bool state){
		if (state) {
			CurrentState = CarShowState.ZOOM_ININFG;
			float zoomInTime = 1;
			Ease zoomInEaseType = Ease.InOutBounce;
			float zoomInScalex = 1;

			hightCarModel.gameObject.SetActive (true);
			lowCarModel.gameObject.SetActive (false);


			//hightCarModel.transform.position = new Vector3 (0, 0f, 0);
			hightCarModel.transform.localScale = new Vector3 (0.2f, 0.2f, 0.2f);

			Tweener tween = hightCarModel.transform.DOScale (Vector3.one * zoomInScalex, zoomInTime);
			tween.SetEase (zoomInEaseType);
			tween.OnComplete ( delegate() {
				Debug.LogError("高模放大完成....");
				CurrentState = CarShowState.BIG;
				TweenComplete( CompleteType.Zoomin);
			});

		} else {
			CurrentState = CarShowState.ZOOM_OUTING;
			Vector3 zoomOutScale = new Vector3 (0.2f, 0.2f, 0.2f);
			float zoomOutTime = 1;
			Ease zoomOutEaseType = Ease.InElastic;

			Tweener tween = hightCarModel.transform.DOScale (zoomOutScale, zoomOutTime);
			tween.SetEase (zoomOutEaseType);
			tween.OnComplete (delegate() {
				Debug.LogError("高模缩小完成....");
				TweenComplete( CompleteType.Zoomout);

			});
		}
	
	}

	public enum CompleteType{
		Grap,	//抓取完成
		Fall,	//落地完成
		Zoomin,	//放大完成
		Zoomout,//缩小完成
		RockBack,//回滚完成
	}

	void TweenComplete(CompleteType type){
		if (!isStartReset) {
			if (type == CompleteType.Grap) {
				
			} else if (type == CompleteType.Fall) {
				ZoomCar (true);
			} else if (type == CompleteType.Zoomin) {
				
			} else if (type == CompleteType.Zoomout) {
				RockBack ();
			} else if (type == CompleteType.RockBack) {
				isStartReset = false;
			}
		} else {

			if (type == CompleteType.Grap) {

			} else if (type == CompleteType.Fall) {
				
			} else if (type == CompleteType.Zoomin) {
				RockBack ();
			} else if (type == CompleteType.Zoomout) {
				RockBack ();
			} else if (type == CompleteType.RockBack) {
				isStartReset = false;
			}

		}
	}

	void RockBack(){
		if (CurrentState == CarShowState.ROLLBACK)
			return;
		
		hightCarModel.gameObject.SetActive(false);
		lowCarModel.gameObject.SetActive(true);

		lowCarModel.transform.localScale = hightCarModel.transform.localScale;
		lowCarModel.transform.position = hightCarModel.transform.position;
		lowCarModel.transform.localEulerAngles = hightCarlRig.transform.localEulerAngles;

		CurrentState = CarShowState.ROLLBACK;
		index = 0;
		eulerList.Reverse();
		points.Reverse();
		lowCarRig.useGravity = false;
		lowCarRig.isKinematic = true;

		DOTween.To (() => index, x => index = x, points.Count - 1, 3).SetEase (Ease.Linear).OnComplete(delegate() {

			lowCarRig.GetComponent<BoxCollider> ().enabled = true;
			lowCarRig.isKinematic = true;
			lowCarRig.velocity = Vector3.zero;
			lowCarRig.angularVelocity = Vector3.zero;



			lowCarRig.useGravity = true;
			lowCarRig.isKinematic = false;

			CurrentState = CarShowState.NORMAL;
			eulerList.Clear ();
			points.Clear ();

			TweenComplete( CompleteType.RockBack);

		});
	}

	//回到初始位置
	void BackInitPosition(){
		
	}


	public bool isStartReset = false;
	public void Rest(){
		if (!isStartReset) {//开始重置
			isStartReset = true;

			if (points.Count > 0) {
				RockBack ();
			} else {
				RestComplete ();
			}
		}
	}
		


	#endregion




}
